
#include "GameplayState.h"
#include "../../SGD Wrappers/CSGD_Direct3D.h"
#include "../../SGD Wrappers/CSGD_DirectInput.h"
#include "../../SGD Wrappers/CSGD_TextureManager.h"
#include "../../SGD Wrappers/CSGD_XAudio2.h"
#include "../../SGD Wrappers/SGD_String.h"
#include "../../SGD Wrappers/SGD_Math.h"
#include "EntityManager.h"
#include "EventSystem.h"
#include "Entity.h"
#include "Waypoint.h"
#include "Spawnpoint.h"
#include "Enemy.h"
#include "Bullet.h"
#include "Tower.h"
#include "ParticleManager.h"
#include "BitmapFont.h"
#include "CreditsState.h"
#include "MainMenuState.h"
#include "Game.h"
#include "BitmapFont.h"
#include <cassert>


//Singleton accessor
GameplayState* GameplayState::GetInstance(void)
{
	static GameplayState s_Instance;
	return &s_Instance;
}


//Constructor
GameplayState::GameplayState(void)
{
	entityManager		= nullptr;
	particleManager		= nullptr;
	eventSystem			= nullptr;
	paused				= false;
	pausedCursor		= 0;
	waveVictory			= false;
	waveDefeat			= false;
}


//Destructor
GameplayState::~GameplayState(void)
{
}


//Enter
void GameplayState::Enter(void)
{
	paused			= false;
	pausedCursor	= 0;
	waveVictory		= false;
	waveDefeat		= false;
	entityManager	= EntityManager::GetInstance();
	particleManager	= ParticleManager::GetInstance();
	eventSystem		= EventSystem::GetInstance();particleManager->Load();
	GameSpeed		= 1.0f;
	quit			= false;

	//Register for events
	eventSystem->Register("WAVE_VICTORY", this);
	eventSystem->Register("WAVE_DEFEAT", this);

	/////////////////////////////////////////////////////////////////////////////////////
	//////    ENTITY TEST     ///////////////////////////////////////////////////////////
	//Entity* testEnemy  = entityManager->CreateEntity(ENTITY_ENEMY,  400.0f, 400.0f);
	//Entity* testTower  = entityManager->CreateEntity(ENTITY_TOWER,  150.0f, 450.0f);
	//Entity* testTank   = entityManager->CreateEntity(ENTITY_TANK,   350.0f, 500.0f);
	//testWaypoint1 = new Waypoint();
	//testWaypoint2 = new Waypoint();
	//testWaypoint3 = new Waypoint();
	//testWaypoint1->x = 100;
	//testWaypoint1->y = 100;
	//testWaypoint1->next = testWaypoint2;
	//testWaypoint2->x = 200;
	//testWaypoint2->y = 100;
	//testWaypoint2->next = testWaypoint3;
	//testWaypoint3->x = 200;
	//testWaypoint3->y = 200;
	//testWaypoint3->next = testWaypoint1;
	//dynamic_cast<Enemy*>(testEnemy)->currentWaypoint = testWaypoint1;
	/////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////


	/////////////////////////////////////////////////////////////////////////////////////
	////////    LEVEL TEST    ///////////////////////////////////////////////////////////
	TiXmlDocument tinyDoc;
	const char* fileName = "TestLevel.xml";
	if(tinyDoc.LoadFile(fileName))
	{
		TiXmlElement* document = tinyDoc.RootElement();
		if (document)
		{
			//Load tank
			TiXmlElement* tank = document->FirstChildElement("Tank");
			double tankX = 0.0;
			tank->Attribute("X",&tankX);
			double tankY = 0.0;
			tank->Attribute("Y",&tankY);
			Entity* newTank = entityManager->CreateEntity(ENTITY_TANK, (float)tankX, (float)tankY);

			//Load towers
			TiXmlElement* tower = document->FirstChildElement("Towers");
			tower = tower->FirstChildElement("Tower");
			while(tower)
			{
				double towerX = 0.0;
				tower->Attribute("X",&towerX);
				double towerY = 0.0;
				tower->Attribute("Y",&towerY);
				double towerRotation = 0.0;
				tower->Attribute("Rotation",&towerRotation);
				Entity* newTower = entityManager->CreateEntity(ENTITY_TOWER, (float)towerX, (float)towerY);
				newTower->rotation = (float)towerRotation;
				tower = tower->NextSiblingElement("Tower");
			}

			//Load waypoints
			int nextWaypoints[100];
			for (int i = 0; i < 100; i++)
			{
				nextWaypoints[i] = 0;
				waypoints[i] = nullptr;
			}
			TiXmlElement* waypoint = document->FirstChildElement("Waypoints");
			waypoint = waypoint->FirstChildElement("Waypoint");
			while(waypoint)
			{
				double waypointID = 0.0;
				waypoint->Attribute("ID",&waypointID);
				double waypointNext = 0.0;
				waypoint->Attribute("Next",&waypointNext);
				nextWaypoints[(int)waypointID] = (int)waypointNext;
				double waypointX = 0.0;
				waypoint->Attribute("X",&waypointX);
				double waypointY = 0.0;
				waypoint->Attribute("Y",&waypointY);
				waypoints[(int)waypointID] = new Waypoint();
				waypoints[(int)waypointID]->x = (float)waypointX;
				waypoints[(int)waypointID]->y = (float)waypointY;
				waypoint = waypoint->NextSiblingElement("Waypoint");
			}
			for (int i = 0; i < 100; i++) //Link waypoints
			{
				if (waypoints[i])
				{
					waypoints[i]->next = waypoints[nextWaypoints[i]];
				}
			}

			//Load spawn points
			Entity* newSpawnpoint = entityManager->CreateEntity(ENTITY_SPAWNPOINT, 70, 70);
			dynamic_cast<Spawnpoint*>(newSpawnpoint)->firstWaypoint = waypoints[1];
			//Load enemies
			//Load bullets
		}
	}
	/////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////
}


//Exit
void GameplayState::Exit(void)
{
	//Unregister for events
	eventSystem->Unregister("WAVE_VICTORY", this);
	eventSystem->Unregister("WAVE_DEFEAT", this);

	entityManager->Shutdown();
	particleManager->DestroyEmitters();
	eventSystem->Shutdown();

	for (int i = 0; i < 100; i++)
	{
		if (waypoints[i])
			delete waypoints[i];
	}
}


//Input
bool GameplayState::Input(void)
{
	CSGD_DirectInput* pDI = CSGD_DirectInput::GetInstance();
	static int lastMouseY = 0;

	//Exit to main menu
	//if(pDI->KeyPressed(DIK_ESCAPE) == true)
	//{
	//	paused = false;
	//	Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
	//	return true;
	//}
	if (quit)
		Game::GetInstance()->ChangeState(CreditsState::GetInstance());

	if (pDI->KeyPressed(DIK_ESCAPE))
	{
		paused = !paused;
		return true;
	}

	if (paused)
	{
		if (pDI->KeyPressed(DIK_UP))
		{
			lastMouseY = pDI->MouseGetPosY();
			--pausedCursor;
			if (pausedCursor < 0)
				pausedCursor = 2;
		}

		if (pDI->KeyPressed(DIK_DOWN))
		{
			lastMouseY = pDI->MouseGetPosY();
			++pausedCursor;
			if (pausedCursor > 2)
				pausedCursor = 0;
		}

		if (pDI->KeyPressed(DIK_RETURN) || pDI->MouseButtonPressed(0))
		{
			if (pausedCursor == 0)
				paused = !paused;
			if (pausedCursor == 1)
			{
			}
			if (pausedCursor == 2)
			{
				paused = false;
				Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
				return true;
			}
		}
	}

	int y = pDI->MouseGetPosY();
	if (y != lastMouseY)
	{
		lastMouseY = 0;
		if (y < 360) 
			pausedCursor = 0;
		else if (y < 420)
			pausedCursor = 1;
		else
			pausedCursor = 2;
	}

	return true;
}


//Update
void GameplayState::Update(float fElapsedTime)
{


	// Update the turrets' fire timer
	//m_fFireTimer += fElapsedTime;
	if( GameSpeed > 2.0f )
	{
		GameSpeed = 0.0f;
	}

	fElapsedTime *= GameSpeed;

	// Update the Entity Manager
	if (!paused)
	{
		entityManager->Update(fElapsedTime);
		particleManager->Update(fElapsedTime);
		eventSystem->Update();
	}
}


//Render
void GameplayState::Render(void)
{
	CBitmapFont* pFont = Game::GetInstance()->GetFont();

	entityManager->Render();
	particleManager->Render();

	//Draw ground
	//RECT rect = {0,650,1024,768};
	//CSGD_Direct3D::GetInstance()->DrawRect(rect, D3DCOLOR_ARGB(120,180,140,100));

	if (waveVictory)
		pFont->Draw(_T("Wave complete"), 300, 220, 1.0f, D3DCOLOR_ARGB(255,255,255,255));

	if (waveDefeat)
		pFont->Draw(_T("Wave failed"), 300, 220, 1.0f, D3DCOLOR_ARGB(255,255,255,255));

	if (paused)
	{

		pFont->Draw(_T("PAUSED"), 300, 220, 1.0f, D3DCOLOR_ARGB(255,255,255,255));

		pFont->Draw(_T("Continue"),          330, 320, 0.8f, D3DCOLOR_ARGB(255,255,255,255));
		pFont->Draw(_T("Save"),              330, 380, 0.8f, D3DCOLOR_ARGB(255,255,255,255));
		pFont->Draw(_T("Exit to main menu"), 330, 440, 0.8f, D3DCOLOR_ARGB(255,255,255,255));

		if (pausedCursor == 0)
			pFont->Draw(_T(">"), 290, 320, 0.8f, D3DCOLOR_ARGB(255,255,255,255));
		if (pausedCursor == 1)
			pFont->Draw(_T(">"), 290, 380, 0.8f, D3DCOLOR_ARGB(255,255,255,255));
		if (pausedCursor == 2)
			pFont->Draw(_T(">"), 290, 440, 0.8f, D3DCOLOR_ARGB(255,255,255,255));
	}
}


//Quit
void GameplayState::Quit(void)
{
	quit = true;
}


//Handle event
void GameplayState::HandleEvent(Event* e)
{
	EntityManager* entityManager = EntityManager::GetInstance();

	//Wave victory
	if (strcmp(e->GetEventType().c_str(),"WAVE_VICTORY") == 0)
	{
		waveVictory = true;
	}

	//Wave defeat
	if (strcmp(e->GetEventType().c_str(),"WAVE_DEFEAT") == 0)
	{
		waveDefeat = true;
	}
}
